package com.luoshizhen.lease.web.app.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.luoshizhen.lease.common.constant.RedisConstant;
import com.luoshizhen.lease.common.login.LoginUserHolder;
import com.luoshizhen.lease.model.entity.*;
import com.luoshizhen.lease.model.enums.ItemType;
import com.luoshizhen.lease.web.app.mapper.*;
import com.luoshizhen.lease.web.app.service.ApartmentInfoService;
import com.luoshizhen.lease.web.app.service.BrowsingHistoryService;
import com.luoshizhen.lease.web.app.service.RoomInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.luoshizhen.lease.web.app.vo.apartment.ApartmentItemVo;
import com.luoshizhen.lease.web.app.vo.attr.AttrValueVo;
import com.luoshizhen.lease.web.app.vo.fee.FeeValueVo;
import com.luoshizhen.lease.web.app.vo.graph.GraphVo;
import com.luoshizhen.lease.web.app.vo.room.RoomDetailVo;
import com.luoshizhen.lease.web.app.vo.room.RoomItemVo;
import com.luoshizhen.lease.web.app.vo.room.RoomQueryVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author liubo
 * @description 针对表【room_info(房间信息表)】的数据库操作Service实现
 * @createDate 2023-07-26 11:12:39
 */
@Service
@Slf4j
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo>
        implements RoomInfoService {

    @Autowired
    private RoomInfoMapper roomInfoMapper;

    @Autowired
    private GraphInfoMapper graphInfoMapper;

    @Autowired
    private LeaseTermMapper leaseTermMapper;

    @Autowired
    private FacilityInfoMapper facilityInfoMapper;

    @Autowired
    private LabelInfoMapper labelInfoMapper;

    @Autowired
    private PaymentTypeMapper paymentTypeMapper;

    @Autowired
    private AttrValueMapper attrValueMapper;

    @Autowired
    private FeeValueMapper feeValueMapper;

    @Autowired
    private ApartmentInfoService apartmentInfoService;

    @Autowired
    private BrowsingHistoryService browsingHistoryService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 根据查询条件分页获取房间项目信息
     *
     * @param page 分页对象，包含分页参数如当前页码、每页大小等
     * @param queryVo 查询条件封装对象，包含查询所需的各个条件
     * @return 返回一个分页对象，包含查询结果和分页信息
     */
    @Override
    public IPage<RoomItemVo> pageRoomItemByQuery(Page<RoomItemVo> page, RoomQueryVo queryVo) {
        // 调用roomInfoMapper中的分页查询方法，传入分页对象和查询条件，获取查询结果
        return roomInfoMapper.pageItem(page, queryVo);
    }

    /**
     * 根据房间ID获取房间详细信息
     * 首先尝试从Redis中获取缓存的房间详情，如果未命中，则从数据库中查询相关信息，并存入Redis中
     * 此方法涉及多个数据表的查询，包括房间信息、图片、租期、配套、标签、支付方式、基本属性、杂费信息和公寓信息
     * 最后，将查询到的信息组合成RoomDetailVo对象返回，并保存用户的浏览历史
     *
     * @param id 房间ID
     * @return RoomDetailVo 房间详细信息对象，包含房间的各种详细数据
     */
    @Override
    public RoomDetailVo getDetailById(Long id) {

        // 构造Redis缓存的键
        String key = RedisConstant.APP_ROOM_PREFIX+id;
        // 尝试从Redis中获取缓存的房间详情
        RoomDetailVo roomDetailVo = (RoomDetailVo) redisTemplate.opsForValue().get(key);
        if (roomDetailVo == null) {
            // 从数据库中查询房间信息
            RoomInfo roomInfo = roomInfoMapper.selectById(id);
            if (roomInfo == null) {
                return null;
            }
            // 查询房间图片
            List<GraphVo> graphVoList = graphInfoMapper.selectListByItemTypeAndId(ItemType.ROOM, id);
            // 查询租期信息
            List<LeaseTerm> leaseTermList = leaseTermMapper.selectListByRoomId(id);
            // 查询配套设施信息
            List<FacilityInfo> facilityInfoList = facilityInfoMapper.selectListByRoomId(id);
            // 查询标签信息
            List<LabelInfo> labelInfoList = labelInfoMapper.selectListByRoomId(id);
            // 查询支付方式信息
            List<PaymentType> paymentTypeList = paymentTypeMapper.selectListByRoomId(id);
            // 查询基本属性信息
            List<AttrValueVo> attrValueVoList = attrValueMapper.selectListByRoomId(id);
            // 查询杂费信息
            List<FeeValueVo> feeValueVoList = feeValueMapper.selectListByApartmentId(roomInfo.getApartmentId());
            // 查询公寓信息
            ApartmentItemVo apartmentItemVo = apartmentInfoService.selectApartmentItemVoById(roomInfo.getApartmentId());

            // 创建RoomDetailVo对象并填充查询到的数据
            roomDetailVo = new RoomDetailVo();
            BeanUtils.copyProperties(roomInfo, roomDetailVo);

            roomDetailVo.setApartmentItemVo(apartmentItemVo);
            roomDetailVo.setGraphVoList(graphVoList);
            roomDetailVo.setAttrValueVoList(attrValueVoList);
            roomDetailVo.setFacilityInfoList(facilityInfoList);
            roomDetailVo.setLabelInfoList(labelInfoList);
            roomDetailVo.setPaymentTypeList(paymentTypeList);
            roomDetailVo.setFeeValueVoList(feeValueVoList);
            roomDetailVo.setLeaseTermList(leaseTermList);

            // 打印获取房间详情的日志
            System.out.println("获取房间详情-"+Thread.currentThread().getName());
            // 将组装好的房间详情信息存入Redis缓存
            redisTemplate.opsForValue().set(key, roomDetailVo);
        }

        // 保存用户浏览历史
        browsingHistoryService.saveHistory(LoginUserHolder.getLoginUser().getUserId(), id);

        // 返回房间详情信息
        return roomDetailVo;
    }

    /**
     * 根据公寓ID分页查询房间项
     *
     * @param page 分页对象，包含分页查询所需的信息，如当前页数、页面大小等
     * @param id 公寓ID，用于指定要查询的公寓
     * @return 返回一个分页的房间项列表，包含满足条件的房间信息
     */
    @Override
    public IPage<RoomItemVo> pageItemByApartmentId(IPage<RoomItemVo> page, Long id) {
        return roomInfoMapper.pageItemByApartmentId(page, id);
    }
}




